package com.wechat.third.controller;

import com.wechat.third.config.WechatThirdConfig;
import com.wechat.third.error.WechatErrorException;
import com.wechat.third.message.WechatMpXmlMessage;
import com.wechat.third.message.WechatMpXmlOutMessage;
import com.wechat.third.message.WechatThirdXmlMessage;
import com.wechat.third.result.auth.ApiQueryAuthInfo;
import com.wechat.third.service.WechatNotifyService;
import com.wechat.third.service.WechatThirdAuthService;
import com.wechat.third.util.FastJsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author
 * @date 2018/12/4
 */
@RestController
@RequestMapping("/wechat/third/notify")
public class WechatNotifyController {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());


	@Autowired
	private WechatNotifyService wechatNotifyService;
	@Autowired
	private WechatThirdConfig wechatThirdConfig;
	@Autowired
	private WechatThirdAuthService wechatThirdAuthService;


	/**
	 * 微信授权事件的接收
	 * @param requestBody
	 * @param timestamp
	 * @param nonce
	 * @param signature
	 * @param encType
	 * @param msgSignature
	 * @return
	 */
	@RequestMapping("/receive_ticket")
	public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp,
								@RequestParam("nonce") String nonce, @RequestParam("signature") String signature,
								@RequestParam(name = "encrypt_type", required = false) String encType,
								@RequestParam(name = "msg_signature", required = false) String msgSignature) {
		this.logger.info(
				"\n接收微信请求：[signature=[{}], encType=[{}], msgSignature=[{}],"
						+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
				signature, encType, msgSignature, timestamp, nonce, requestBody);

		if (!StringUtils.equalsIgnoreCase("aes", encType)
				|| !wechatNotifyService.checkSignature(timestamp, nonce, signature)) {
			throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
		}

		// aes加密的消息
		WechatThirdXmlMessage inMessage = WechatThirdXmlMessage.fromEncryptedXml(requestBody,
				wechatThirdConfig, timestamp, nonce, msgSignature);
		this.logger.info("\n消息解密后内容为：\n{} ", inMessage.toString());
		try {
			String out = wechatNotifyService.route(inMessage);
			this.logger.info("\n组装回复信息：{}", out);
		} catch (WechatErrorException e) {
			this.logger.error("receive_ticket", e);
		}


		return "success";
	}


	/**
	 * 消息与事件接收URL
	 * @param requestBody
	 * @param appId
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @param openid
	 * @param encType
	 * @param msgSignature
	 * @return
	 */
	@RequestMapping(value ="/{appId}/callback", method = RequestMethod.POST)
	public Object callback(@RequestBody(required = false) String requestBody,
						   @PathVariable("appId") String appId,
						   @RequestParam("signature") String signature,
						   @RequestParam("timestamp") String timestamp,
						   @RequestParam("nonce") String nonce,
						   @RequestParam("openid") String openid,
						   @RequestParam("encrypt_type") String encType,
						   @RequestParam("msg_signature") String msgSignature) {
		this.logger.info(
				"\n callback接收微信请求：[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"
						+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
				appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
		if (!StringUtils.equalsIgnoreCase("aes", encType)
				|| !wechatNotifyService.checkSignature(timestamp, nonce, signature)) {
			throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
		}
		String out = "";
		// aes加密的消息
		WechatMpXmlMessage wechatMpXmlMessage=WechatMpXmlMessage.fromEncryptedMpXml(requestBody,wechatThirdConfig,timestamp,nonce,msgSignature);
		this.logger.info("\n消息解密后内容为：\n{} ", wechatMpXmlMessage.toString());
		// 全网发布测试用例
		try {
			if (StringUtils.equals(wechatMpXmlMessage.getMsgType(), "text")) {
				/*返回普通文本信息*/
				if (StringUtils.equals(wechatMpXmlMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) {
					String returnContent = wechatMpXmlMessage.getContent()+"_callback";
					Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
					WechatMpXmlOutMessage wechatMpXmlOutMessage=WechatMpXmlOutMessage.builder()
							.content(returnContent)
							.fromUserName(wechatMpXmlMessage.getToUser())
							.toUserName(wechatMpXmlMessage.getFromUser())
							.createTime(createTime)
							.msgType("text")
							.build();
					out=WechatMpXmlOutMessage.wechatMpOutXmlMessageToEncryptedXml(wechatMpXmlOutMessage,wechatThirdConfig);
				}else if (StringUtils.startsWith(wechatMpXmlMessage.getContent(), "QUERY_AUTH_CODE:")) {
					/*全网发布返回api文本信息*/
					String authCode=wechatMpXmlMessage.getContent().split(":")[1];
					ApiQueryAuthInfo apiQueryAuthInfo= wechatThirdAuthService.getApiQueryAuthInfo(authCode);
					Map<String,Object> obj = new HashMap<String,Object>();
					Map<String,Object> msgMap = new HashMap<String,Object>();
					String msg = authCode + "_from_api";
					msgMap.put("content", msg);
					obj.put("touser", wechatMpXmlMessage.getFromUser());
					obj.put("msgtype", "text");
					obj.put("text", msgMap);
					out = wechatThirdAuthService.sendMessage(FastJsonUtils.map2json(obj), apiQueryAuthInfo.getAuthorizationInfo().getAuthorizerAccessToken());
				}
			} else if (StringUtils.equals(wechatMpXmlMessage.getMsgType(), "event")) {
				/*发送事件信息(返回文本信息)*/
				String content = wechatMpXmlMessage.getEvent() + "from_callback";
				Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
				WechatMpXmlOutMessage wechatMpXmlOutMessage=WechatMpXmlOutMessage.builder()
						.content(content)
						.fromUserName(wechatMpXmlMessage.getToUser())
						.toUserName(wechatMpXmlMessage.getFromUser())
						.createTime(createTime)
						.msgType("text")
						.build();
				out=WechatMpXmlOutMessage.wechatMpOutXmlMessageToEncryptedXml(wechatMpXmlOutMessage,wechatThirdConfig);
			}
		}catch (Exception e) {
			logger.error("callback", e);
		}
		logger.info("\n消息与事件接收URL：out=[{}] ",out);
		return out;
	}



}
